import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.io.*;
import java.math.BigInteger;
import java.security.Key;
import java.util.Scanner;

public class DES_Use {
    //文件转换为byte[]类型，并返回。
    public static byte[] getByte(String name) throws Exception{
        String fileName = name;
        FileInputStream fis = new FileInputStream(fileName);
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[]{};
        int len = 0;
        // 将内容读到buffer中，读到末尾为-1
        while ((len = fis.read(buffer)) != -1) {
            // 本例子将每次读到字节数组(buffer变量)内容写到内存缓冲区中，起到保存每次内容的作用
            outStream.write(buffer, 0, len);
        }
        byte[] data = outStream.toByteArray(); // 取内存中保存的数据
        fis.close();
        System.out.println("文件完成转换");
        return data;
    }
    //密钥的生成及保存。
    public static BigInteger produceDEAKey() throws Exception {
        KeyGenerator kg = KeyGenerator.getInstance("DESede");//1.获取密钥生成器
        kg.init(168);//初始化密钥生成器，DESede算法密钥长度为112,168位。DES算法密钥长度必须为56位
        SecretKey k = kg.generateKey();//生成密钥
        byte[ ] kb=k.getEncoded( );
        BigInteger bigInteger=new BigInteger(kb);
        FileOutputStream f = new FileOutputStream("DESkey.dat");//指定产生密钥输出流文件
        ObjectOutputStream b = new ObjectOutputStream(f);//将对象序列化，以流的方式进行处理
        b.writeObject(k);//通过以对象序列化方式将密钥保存在文件中
        System.out.println("DES密钥生成完成");
        return bigInteger;
    }
    //将DES的密钥转换为字节码文件
    public static BigInteger setBigInteger ()throws Exception {
        FileInputStream f = new FileInputStream("DESkey.dat");//指定文件输入流
        ObjectInputStream b = new ObjectInputStream(f);//将文件输入流f作为参数传递给对象输入流
        Key k = (Key) b.readObject();//执行对象输入流的readObject()方法读取密钥对象。由于该方法返回的是Objecj类型，需要强制转换为key类型
        byte[] kb = k.getEncoded();//获取主要编码格式，在执行SecretKey类型的对象k的getEncoded()方法，返回的编码放在byte类型的数组中
        FileOutputStream f2 = new FileOutputStream("keykb1.dat");//指定文件输出流
        f2.write(kb);//保存密钥编码
        System.out.println("DES密钥完成字节码保存");
        BufferedReader in =
                new BufferedReader(new InputStreamReader(
                        new FileInputStream("keykb1.dat")));
        BigInteger c = new BigInteger(kb);
        return c;
        //String s="Hello World!";
        //        byte ptext[]=s.getBytes("UTF8");
        //        BigInteger m=new BigInteger(ptext);
    }
    //DESede加密，返回密文。
    public static byte[] EncryptionDES(byte[]data) throws Exception {
        FileInputStream f = new FileInputStream("DESkey.dat");
        ObjectInputStream b = new ObjectInputStream(f);
        Key k = (Key) b.readObject();//从文件中获取密钥
        Cipher cp = Cipher.getInstance("DESede");//创建密码器
        cp.init(Cipher.ENCRYPT_MODE, k);//初始化密码器，第一个参数指定密码器准备进行加密还是解密，第二个参数则传入加密或解密所使用的密钥。
        byte ctext[] = cp.doFinal(data);//执行Cipher对象的doFinal()方法，该方法的参数中传入待加密的明文，从而按照前面设置的算法与模式对明文加密。
        System.out.println("DES加密完成！");
        FileOutputStream f2 = new FileOutputStream("Ciphertext.txt");//将密文保存于Ciphertext.dat中。
        f2.write(ctext);//处理加密结果
        return ctext;
    }
    //DESede解密，信息保存。
    public static void DecryptionDES(byte[]data) throws Exception{
        FileInputStream f = new FileInputStream("DESkey.dat");
        ObjectInputStream b = new ObjectInputStream(f);
        Key k = (Key) b.readObject();//从文件中获取密钥
        Cipher cp = Cipher.getInstance("DESede");//创建密码器
        cp.init(Cipher.DECRYPT_MODE,k);
        byte ctext[]=cp.doFinal(data);
        FileOutputStream ff=new FileOutputStream("Plaintext1.txt");
        ff.write(ctext);
        System.out.println("DES密钥解密完成！");
    }
    public static void DecryptionRSA_DES(byte []data,Key k) throws Exception{
        Cipher cp = Cipher.getInstance("DESede");//创建密码器
        cp.init(Cipher.DECRYPT_MODE,k);
        byte ctext[]=cp.doFinal(data);
        FileOutputStream ff=new FileOutputStream("Plaintext2.txt");
        ff.write(ctext);
        System.out.println("使用通过RAS私钥解密的DES密钥解密完成！");
    }
}

